import sys

from sklearn.datasets import load_svmlight_file
from sklearn import svm
from sklearn import tree
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
clf = svm.SVC(kernel="rbf", C=1000, gamma=0.01)
#clf = tree.DecisionTreeClassifier()
#clf = RandomForestClassifier(n_estimators=60)
#clf = KNeighborsClassifier(10, algorithm='ball_tree')
#clf = GradientBoostingClassifier()
n_features = 0
def Distribute(setting, i, cur, t, fold, r):
    setting[i][t] = []
    for p in range(fold):
        setting[i][t].append(cur)
        cur += 1
        if (cur == r):
            cur = 0
    return cur

def ProduceExperimentSettings(r, train_fold, test_fold):
    setting = []
    for i in range(r):
        setting.append({})
	cur = Distribute(setting, i, i, "train", train_fold, r)
	cur = Distribute(setting, i, cur, "test", test_fold, r)

    return setting

def CreateDataFile(path, suffix):
    f = open(path, "w")
    for i in suffix:
        f.write(open(prefix + "_" + str(i), "r").read())
    f.close()

def Train(suffix):
    global clf, n_features
    path = tmpDir + "training_set"
    CreateDataFile(path, suffix)
    features, labels = load_svmlight_file(path)
    n_features = features.shape[1]
#    clf.fit(features, labels)
    clf.fit(features.toarray(), labels)

def Predict(suffix, msg):
    global clf
    path = tmpDir + "testing_set"
    CreateDataFile(path, suffix)

    f = open(path, "r")
    contents = f.read()
    f.close()

    lines = contents.split("\n")

    f = open(path, "w")
    f.write(lines[0] + " {0}:0\n".format(n_features) + "\n".join(lines[1:]))
    f.close()

    features, trueLabels = load_svmlight_file(path)
#    labels = clf.predict(features)
    labels = clf.predict(features.toarray())

    correct = 0
    total = len(labels)

    for i in range(total):
        if labels[i] == trueLabels[i]:
	    correct += 1

    print msg, "Accuracy = {0:.4f}% ({1}/{2})".format(float(correct) / total * 100, correct, total)
    return correct, total

def RunExperiment(run):
    Train(run["train"])
    correct, total = Predict(run["test"], "Testing")
    return correct, total


if len(sys.argv) < 4:
    print "Usage: python DirectRun.py working-dir test-file-prefix r-folds"
    sys.exit()

if sys.argv[1][-1] != '/':
    sys.argv[1] += '/'

prefix = sys.argv[1] + sys.argv[2]
r = int(sys.argv[3])

tmpDir = "/p/paradyn/development/xmeng/workspaces/binary-classification/test/tmp1/"

test_fold = 1
train_fold = r - test_fold

setting = ProduceExperimentSettings(r, train_fold, test_fold)

correct = 0
total = 0
for run in setting:
    c, t = RunExperiment(run)
    correct += c
    total += t
print "Average Accuracy = {0:.4f}% ({1}/{2})".format(float(correct) / total * 100, correct, total)

